package com.mayikt;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * @ClassName MayiktCountDownLatch
 * @Author 蚂蚁课堂余胜军 QQ644064779 www.mayikt.com
 * @Version V1.0
 **/
public class MayiktCountDownLatch {
    private Sync sync;

    public MayiktCountDownLatch(int count) {
        sync = new Sync(count);
    }

    /**
     * 让当前线程变为阻塞状态
     */
    public void await() {
        sync.acquireShared(1);
    }

    public void countDown() {
        sync.releaseShared(1);
    }

    class Sync extends AbstractQueuedSynchronizer {
        public Sync(int count) {
            setState(count);
        }

        /**
         * 如果该返回结果是<0的情况下，则让当前线程放入到aqs双向链表中
         *
         * @param arg
         * @return
         */
        @Override
        protected int tryAcquireShared(int arg) {
            // 如果aqs的状态>0,则让当前线程放入到aqs双向链表中 返回<0 -1;
            //  return (getState() <=0) ? 1 : -1;
            return getState() == 0 ? 1 : -1;
        }

        /**
         * 如果该方法返回true的情况下，就唤醒刚才阻塞的线程
         * getState() == 0 -1 ==0 true
         * >0 false
         *
         * @param arg
         * @return
         */
        @Override
        protected boolean tryReleaseShared(int arg) {
            for (; ; ) {
                int oldState = getState();
                if (oldState == 0) {
                    return false;
                }
                int newState = oldState - arg;
                if (compareAndSetState(oldState, newState)) {
                    return newState == 0;
                }
            }
        }
    }

    public static void main(String[] args) {
        MayiktCountDownLatch mayiktCountDownLatch = new MayiktCountDownLatch(2);
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + ":1");
            mayiktCountDownLatch.await();
            System.out.println(Thread.currentThread().getName() + ":2");
        }).start();
        mayiktCountDownLatch.countDown();
        mayiktCountDownLatch.countDown();
    }
}
